package site.wlwsjsx.iot_backend.controller;

import com.google.gson.Gson;
import io.micrometer.common.util.StringUtils;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import site.wlwsjsx.iot_backend.service.ReceiveService;
import site.wlwsjsx.iot_backend.utils.BodyObjUtil;
import site.wlwsjsx.iot_backend.utils.OneNetUtil;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

@RestController
public class ReceiveController {
    private static final Logger logger = LoggerFactory.getLogger(ReceiveController.class);

    private static final String RETURN = "ok";

    private static final String TOKEN = "wlwsjsx";

    private static final String AES_KEY = "8LcUPQMQqPHWkb4a";//aesKey和OneNet推送配置里的aesKey一致

    @Resource
    private ReceiveService receiveService;

    /**
     * 功能说明： URL&Token验证接口。如果验证成功返回msg的值，否则返回其他值。
     *
     * @param msg       验证消息
     * @param nonce     随机串
     * @param signature 签名
     * @return msg值
     */
    @GetMapping("/receive")
    public String check(@RequestParam String msg,
                        @RequestParam String nonce,
                        @RequestParam String signature) {
        logger.info("receive check msg:{},nonce:{},signature:{}", msg, nonce, signature);
        if (OneNetUtil.checkToken(msg, nonce, signature, TOKEN)) {
            return msg;
        }
        return "no";
    }

    /**
     * 功能描述：第三方平台数据接收。 <p>
     * <ul>注:
     * <li>1.OneNet平台为了保证数据不丢失，有重发机制，如果重复数据对业务有影响，数据接收端需要对重复数据进行排除重复处理。</li>
     * <li>2.OneNet每一次post数据请求后，等待客户端的响应都设有时限，在规定时限内没有收到响应会认为发送失败。
     * 接收程序接收到数据时，尽量先缓存起来，再做业务逻辑处理。</li>
     * <li>3.AES_KEY配置为空时为明文逻辑，不为空时视作密文传输做解密操作</li>
     * </ul>
     *
     * @param body 数据消息
     * @return 任意字符串。OneNet平台接收到http 200的响应，才会认为数据推送成功，否则会重发。
     */
    @PostMapping("/receive")
    public String receive(@RequestBody String body) throws InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException {
        BodyObjUtil obj1 = OneNetUtil.resolveNewBody(body);
        logger.info("data receive:  body Object--- {}", new Gson().toJson(obj1));
        if (obj1 != null) {
            if (OneNetUtil.checkSignature(obj1, TOKEN)) {
                String msg = StringUtils.isEmpty(AES_KEY) ? obj1.toString() : OneNetUtil.decryptNewMsg(obj1.getMsg().toString(), AES_KEY);
                logger.info("data receive: content {}", msg);
                receiveService.dealMessageFromJson(msg);
            } else {
                logger.info("data receive:  signature error ");
                return "signature error";
            }
        } else {
            logger.info("data receive: body empty error");
            return "body empty error";
        }
        return RETURN;
    }
}
